/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.boot.web.interceptor;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.iwindplus.boot.domain.constant.CommonConstant.ExceptionConstant;
import com.iwindplus.boot.domain.constant.CommonConstant.TraceConstant;
import com.iwindplus.boot.web.manager.context.ContextTransManager;
import jakarta.annotation.Resource;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.protocol.HttpContext;

/**
 * HttpClient拦截器.
 *
 * @author zengdegui
 * @since 2020/4/23
 */
@Slf4j
public class HttpClientInterceptor implements HttpRequestInterceptor {

    @Resource
    private ContextTransManager contextTransManager;

    @Override
    public void process(HttpRequest httpRequest, EntityDetails entityDetails, HttpContext httpContext) throws HttpException, IOException {
        Map<String, String> parameters = this.getStringMap(httpRequest);

        Map<String, String> map = contextTransManager.buildRequestHeaderInMdc(parameters);
        if (MapUtil.isEmpty(map)) {
            return;
        }
        map.entrySet().stream()
            .filter(entry -> ObjectUtil.isNotEmpty(entry.getValue()))
            .forEach(entry -> httpRequest.setHeader(entry.getKey(), entry.getValue()));
    }

    private Map<String, String> getStringMap(HttpRequest httpRequest) {
        Map<String, String> parameters = new HashMap<>(16);
        final Header[] headers = httpRequest.getHeaders();
        if (ArrayUtil.isEmpty(headers)) {
            return parameters;
        }
        for (Header header : headers) {
            parameters.put(header.getName(), header.getValue());
        }
        if (CharSequenceUtil.isNotBlank(parameters.get(TraceConstant.REAL_IP))) {
            return parameters;
        }
        try {
            parameters.put(TraceConstant.REAL_IP, httpRequest.getUri().getHost());
        } catch (URISyntaxException ex) {
            log.error(ExceptionConstant.URI_SYNTAX_EXCEPTION, ex);
        }
        return parameters;
    }
}
